interface SystemInfo {
  screenWidth: number;
  screenHeight: number;
  statusBarHeight: number;
  navBarHeight?: number;
  model: string;
  version: string;
  platform?: "android" | "ios" | "windows" | "devtools";
  pixelRatio?: number;
  sdkVersion?: string;
}

type GetSyncOptions = { withDpi?: boolean };
type GetAsyncOptions = { retry?: number };

const CACHE_TIMEOUT = 1000 * 60; // 1分钟缓存

class SystemInfoManager {
  private static cache: SystemInfo | null = null;
  private static lastFetch = 0;

  // 同步获取方法
  static getSync(options: GetSyncOptions = {}): SystemInfo {
    // #ifdef MP-WEIXIN
    const windowInfo = uni.getWindowInfo();
    const deviceInfo = uni.getDeviceInfo();
    const baseInfo = uni.getAppBaseInfo();

    return {
      screenWidth: windowInfo.screenWidth,
      screenHeight: windowInfo.screenHeight,
      statusBarHeight: windowInfo.statusBarHeight,
      navBarHeight: 44,
      model: deviceInfo.model,
      version: baseInfo.version,
      platform: "devtools",
      ...(options.withDpi && { pixelRatio: windowInfo.pixelRatio }),
    };
    // #endif

    // #ifndef MP-WEIXIN
    const systemInfo = uni.getSystemInfoSync();
    return {
      ...systemInfo,
      ...(options.withDpi && { pixelRatio: systemInfo.pixelRatio }),
    } as SystemInfo;
    // #endif
  }

  // 异步获取方法
  static async getAsync(options: GetAsyncOptions = {}): Promise<SystemInfo> {
    let retryCount = 0;
    const maxRetry = Math.min(options.retry || 1, 3);

    while (retryCount <= maxRetry) {
      try {
        if (Date.now() - this.lastFetch < CACHE_TIMEOUT && this.cache) {
          return this.cache;
        }

        let result: SystemInfo;

        // #ifdef MP-WEIXIN
        const [windowInfo, deviceInfo, baseInfo] = await Promise.all([
          uni.getWindowInfo(),
          uni.getDeviceInfo(),
          uni.getAppBaseInfo(),
        ]);

        result = {
          screenWidth: windowInfo.screenWidth,
          screenHeight: windowInfo.screenHeight,
          statusBarHeight: windowInfo.statusBarHeight,
          navBarHeight: 44,
          model: deviceInfo.model,
          version: baseInfo.version,
          sdkVersion: baseInfo.SDKVersion,
          platform: "devtools",
        };
        // #endif

        // #ifndef MP-WEIXIN
        result = (await uni.getSystemInfo()) as SystemInfo;
        // #endif

        this.cache = result;
        this.lastFetch = Date.now();
        return result;
      } catch (error: any) {
        if (retryCount++ >= maxRetry) {
          throw new Error(`Get system info failed: ${error.message}`);
        }
        await new Promise((resolve) => setTimeout(resolve, 500));
      }
    }
    throw new Error("Unexpected end of getAsync");
  }
}

// 导出兼容方法
export const getSystemInfoSync = SystemInfoManager.getSync;
export const getSystemInfo = SystemInfoManager.getAsync;
export type { SystemInfo, GetSyncOptions, GetAsyncOptions };

export function setCssVar(name: string, value: string | number) {
  // #ifdef H5
  document.documentElement.style.setProperty(
    name,
    typeof value === "number" ? `${value}px` : value
  );
  // #endif

  // #ifdef MP-WEIXIN
  uni.setStorageSync(
    `css${name}`,
    typeof value === "number" ? `${value}px` : value
  );
  // #endif
}

export function getCssVar(name: string) {
  // #ifdef MP-WEIXIN
  return uni.getStorageSync(`css${name}`);
  // #endif

  // #ifdef H5
  return document.documentElement.style.getPropertyValue(name);
  // #endif
}
